package com.agencia.persistencia;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import com.agencia.connection.DataSocketBuscar;
import com.agencia.dominio.Anulado;
import com.agencia.dominio.Terminal;
import com.agencia.dominio.Usuario;
import com.agencia.dominio.Venta;

public class PersistenciaImp implements IPersistencia {
	
	private PersistenciaImp(){};
	
	private static PersistenciaImp instancia = new PersistenciaImp();
	
	public static PersistenciaImp getInstance(){
		return instancia;
	}

	public boolean altaVentaBD(Venta venta) throws SQLException	{ 
		
		String sql_idVenta = "SELECT Valor FROM Configuracion WHERE Parametro = ? LIMIT 1";
		
		Double id_idVenta = (double) 1;
		
		PreparedStatement ps = null;
		PreparedStatement ps1 = null;
		Connection con = null;
		Statement stmt = null;
		ResultSet rs_idVenta = null;
		
		con = DBConn.DataSourceCon();
		con.setAutoCommit(false);
		
		try {
			stmt = con.createStatement();
			rs_idVenta =stmt.executeQuery(sql_idVenta);
			
			while(rs_idVenta.next()) {
				id_idVenta = Double.valueOf(rs_idVenta.getString("Valor")); //.valueOf(rs_idTerminal.getString("valor"));
			}
			
			id_idVenta +=1;
			
			String sql_addventa = "INSERT INTO Ventas (Id_Ticket, " +
					"Id_Ticket_IMM, " +
					"Matricula, " +
					"FechaVenta, " +
					"FechaInicio," +
					"Minutos," +
					"Importe," +
					"Id_Terminal," +
					"Id_Usuario) " +
					"VALUES(?, ?, ?,?,?, ?, ?, ?,?)";
			String sql_increidventa = "UPDATE Configuracion SET Valor =" + id_idVenta.toString() + " WHERE parametro='"+Constants.getIdVentas()+"'";
			
			ps = con.prepareStatement(sql_addventa);
			ps1 = con.prepareStatement(sql_increidventa);
				
			SimpleDateFormat formatd = new SimpleDateFormat("yyyy-MM-dd");
			
			ps.setDouble(1, id_idVenta);         
			ps.setDouble(2, venta.getId_imm());
			ps.setString(3, venta.getMatricula());			
			ps.setString(4,formatd.format(venta.getFechaVenta()));
			ps.setString(5,formatd.format(venta.getFechaInicio()));
			ps.setInt(6, venta.getMinutos());
			ps.setDouble(7, venta.getImporte());
			ps.setDouble(8, venta.getId_terminal());
			ps.setDouble(9, venta.getId_usuario());
			ps = con.prepareStatement(sql_addventa);
			
			
			ps.executeUpdate();
			ps1.executeUpdate();
			con.commit();
			return true;
			
		} catch (Exception e) {
			System.out.println(e.getMessage());
		
					
		}finally {
			if(rs_idVenta != null) rs_idVenta.close();
			if(stmt != null) stmt.close();
			con.setAutoCommit(true);
			if(con != null) con.close();
			
		}
		return false;

	

	}

	public Anulado anularVentaBD(Venta venta, Anulado anulado) throws SQLException {
		String sql_idAnulado = "SELECT Valor FROM Configuracion WHERE parametro = ? LIMIT 1";
		String sql_updidAnulado = "UPDATE Configuracion SET Valor = ? WHERE parametro=?";
		String sql_addAnulado="INSERT INTO Anulaciones (Id_Ticket, Id_Anulado, Id_Anulado_IMM, Fecha, Id_Usuario) VALUES (?, ?, ?, ?, ?)";
		Integer idAnulado = 0;
		Date fechaactual = new Date();
		Timestamp fechaActual = new Timestamp(fechaactual.getTime());
		
		
		PreparedStatement ps_idAnulado = null;
		PreparedStatement ps_updidAnulado = null;
		PreparedStatement ps_addAnulado = null;
		
		Connection con = null;
		ResultSet rs_idAnulado = null;
		
		
		con = DBConn.DataSourceCon();
		con.setAutoCommit(false);
		
		ps_idAnulado = con.prepareStatement(sql_idAnulado);
		ps_updidAnulado = con.prepareStatement(sql_updidAnulado);
		ps_addAnulado = con.prepareStatement(sql_addAnulado);

		ps_idAnulado.setString(1,Constants.getIdAnulaciones());
		
		rs_idAnulado = ps_idAnulado.executeQuery();
		
		while(rs_idAnulado.next()) {
			idAnulado  = rs_idAnulado.getInt("Valor");
		}
		//INCREMENTO Id_Anulado
		idAnulado +=1;
		
		ps_updidAnulado.setInt(1, idAnulado);
		ps_updidAnulado.setString(2, Constants.getIdAnulaciones());
		
		ps_addAnulado.setInt(1, venta.getId());
		ps_addAnulado.setInt(2, idAnulado);
		ps_addAnulado.setInt(3, anulado.getId());
		ps_addAnulado.setTimestamp(4, fechaActual);
		ps_addAnulado.setInt(5, venta.getId_usuario());
		
		ps_updidAnulado.executeUpdate();
		ps_addAnulado.executeUpdate();

		con.setAutoCommit(true);
		
		ps_addAnulado.close();
		rs_idAnulado.close();
		if(con != null) con.close();

		return anulado;
	}

	public boolean ingresarUsuarioBD(Usuario usuario) throws SQLException{ //sdc 12/11/12
		
		String sql_idUsuario = "SELECT Valor FROM Configuracion WHERE Parametro=? LIMIT 1";
		String sql_updidUsuario = "UPDATE Configuracion SET Valor = ? WHERE parametro=?";
		String sql_addUsuario = "INSERT INTO Usuarios (Id, Nombre, Usuario, Password) VALUES(?, ?, ?, MD5(?))";
		Integer id_Usuario = 0;
		
		PreparedStatement ps_idUsuario = null;
		PreparedStatement ps_updidUsuario = null;
		PreparedStatement ps_addUsuario = null;
		
		Connection con = null;
		ResultSet rs_idUsuario = null;
		
		con = DBConn.DataSourceCon();
		con.setAutoCommit(false);
	
		ps_idUsuario = con.prepareStatement(sql_idUsuario);
		ps_updidUsuario = con.prepareStatement(sql_updidUsuario);
		ps_addUsuario = con.prepareStatement(sql_addUsuario);
				
		ps_idUsuario.setString(1,Constants.getIdUsuarios());
		
		rs_idUsuario = ps_idUsuario.executeQuery();
		
		while(rs_idUsuario.next()) {
			id_Usuario  = rs_idUsuario.getInt("Valor");
		}
		//INCREMENTO Id_Usuario
		id_Usuario +=1;
		
		ps_updidUsuario.setInt(1, id_Usuario);
		ps_updidUsuario.setString(2, Constants.getIdUsuarios());
		
		ps_addUsuario.setInt(1, id_Usuario);
		ps_addUsuario.setString(2, usuario.getNombre());
		ps_addUsuario.setString(3, usuario.getUsuario());
		ps_addUsuario.setString(4, usuario.getPass());
		
		ps_updidUsuario.executeUpdate();
		ps_addUsuario.executeUpdate();

		con.setAutoCommit(true);
		
		ps_addUsuario.close();
		rs_idUsuario.close();
		if(con != null) con.close();

		con.commit();
		con.setAutoCommit(true);
		return true;
		
	}

	public boolean modificarUsuarioBD(Usuario usuario) throws SQLException {
		
		String sql_updUsuario = "UPDATE Usuarios SET Nombre = ?," +
				"Usuario = ? " +
				"Password = MD5(?) " +
				"WHERE Id=?";
		
		PreparedStatement ps_updUsuario = null;
		
		Connection con = null;
		
		con = DBConn.DataSourceCon();
		con.setAutoCommit(false);
	
		ps_updUsuario = con.prepareStatement(sql_updUsuario);
		
		ps_updUsuario.setString(1, usuario.getNombre());
		ps_updUsuario.setString(2, usuario.getUsuario());
		ps_updUsuario.setString(3, usuario.getPass());
		ps_updUsuario.setInt(4, usuario.getId());
		
		ps_updUsuario.executeUpdate();

		con.setAutoCommit(true);
		
		ps_updUsuario.close();
		if(con != null) con.close();

		con.commit();
		con.setAutoCommit(true);
		return true;
	}
	
	
	public boolean ingresarTerminalaBD(Terminal terminal) throws TerminalExisteException, TerminalErrorDatosException, SQLException {
		// TODO Auto-generated method stub
		
		if(terminal == null){
			
		}else if(terminal.getDomicilio().equalsIgnoreCase("") || terminal.getNombre().equalsIgnoreCase("") || terminal.getTelefono().equalsIgnoreCase("")){
			throw new TerminalErrorDatosException();
		}else{
			if(buscarTerminalaBD(terminal)){
				throw new TerminalExisteException();
			}
			//String sql_idTerminal = "SELECT valor FROM Configuracion WHERE parametro='"+ Constants.getIdTerminal()+"' LIMIT 1";
			
			String sql_idTerminal = "SELECT Valor FROM Configuracion WHERE Parametro='Id_Terminales' LIMIT 1";
			
			Double id_idTerminal = (double) 1;
			
			PreparedStatement ps = null;
			PreparedStatement ps1 = null;
			Connection con = null;
			Statement stmt = null;
			ResultSet rs_idTerminal = null;
			
			con = DBConn.DataSourceCon();
			con.setAutoCommit(false);
			
			try {
				stmt = con.createStatement();
				rs_idTerminal = stmt.executeQuery(sql_idTerminal);
				
				while(rs_idTerminal.next()) {
					id_idTerminal = Double.valueOf(rs_idTerminal.getString("Valor")); //.valueOf(rs_idTerminal.getString("valor"));
				}
				id_idTerminal +=1;
				
				String sql_addterminal = "INSERT INTO Terminales (id, nombre, domicilio, telefono) VALUES(?, ?, ?, ?)";
				String sql_increidterminal = "UPDATE Configuracion SET Valor =" + id_idTerminal.toString() + " WHERE Parametro='"+Constants.getIdTerminal()+"'";
				
			
				ps1 = con.prepareStatement(sql_increidterminal);
				ps = con.prepareStatement(sql_addterminal);
				ps.setDouble(1, id_idTerminal);            //(id_idTerminal, 1000);
				ps.setString(2, terminal.getNombre());
				ps.setString(3, terminal.getDomicilio());
				ps.setString(4, terminal.getTelefono());
				ps1.executeUpdate();
				
				ps.executeUpdate();
				
				
						
				con.commit();
				return true;
				
			} catch (Exception e) {
				//FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(),""));
				System.out.println(e.getMessage());
				return false;
						
			}finally {
				if(rs_idTerminal != null) rs_idTerminal.close();
				if(stmt != null) stmt.close();
				con.setAutoCommit(true);
				if(con != null) con.close();
				
			}
		}
		return false;
	}

	public boolean modificarTerminalBD(Terminal terminal) {
		return false;
	}

	public boolean existeUsuarioTerminalBD(String us, String pass,int id_terminal) throws SQLException {
		
		String sql_ExisteUsrTer = "SELECT COUNT(Usuarios.Id) AS Cantidad "; 
		sql_ExisteUsrTer += " FROM Usuarios JOIN Usuario_Terminal ON Usuario_Terminal.Id_Usuario = Usuarios.Id ";
		sql_ExisteUsrTer += " WHERE Usuarios.Usuario = ? AND Usuarios.Password = MD5(?) AND Usuario_Terminal.Id_Terminal = ?";
		
		PreparedStatement sql_statement = null;
		Connection con = null;
		ResultSet rs_eUser = null;
		Integer count = 0;
		
		con = DBConn.DataSourceCon();

			sql_statement = con.prepareStatement(sql_ExisteUsrTer);
			sql_statement.setString(1, us); 
			sql_statement.setString(2, pass);
			sql_statement.setInt(3, id_terminal);
			
			rs_eUser = sql_statement.executeQuery();
			rs_eUser.next();
			
			count = rs_eUser.getInt("Cantidad");
			rs_eUser.close();
			
			if(count!=0){
				return true;
			}else{
				return false;
			}
	}

	
	public boolean buscarTerminalaBD(Terminal terminal) {
		return false;
	}

	public boolean loginAdminBD(String us, String pass) {
		return false;
	}
	
	public ArrayList<Terminal> selectAll() throws SQLException{
		
		ArrayList<Terminal> terminales = new ArrayList<Terminal>();
		String sql_ideditorial = "SELECT Nombre, Domicilio, Telefono FROM terminales";
		
		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		
		
		con = DBConn.DataSourceCon();
		con.setAutoCommit(false);
		try {
			
			stmt = con.createStatement();
			rs = stmt.executeQuery(sql_ideditorial);
			
			Terminal t = new Terminal(null, sql_ideditorial, sql_ideditorial, sql_ideditorial);
			
			while (rs.next()){
	            t.setNombre(rs.getString("Nombre"));
	            t.setDomicilio(rs.getString("Domicilio"));
	            t.setTelefono(rs.getString("Telefono"));
	            
	            terminales.add(t);
			}
			
			con.commit();
			
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(rs != null) rs.close();
			if(stmt != null) stmt.close();
			con.setAutoCommit(true);
			if(con != null) con.close();
			
		}
		return terminales;
	}

	public Usuario obtenerUsuario(String user) throws SQLException {
		
		String sql_ExisteUsrTer = "SELECT Usuarios.Id AS id, Usuarios.nombre AS nombre "; 
		sql_ExisteUsrTer += " FROM Usuarios";
		sql_ExisteUsrTer += " WHERE Usuarios.Usuario =?";
		
		PreparedStatement sql_statement = null;
		Connection con = null;
		ResultSet rs_eUser = null;
		Integer id = 0;
		String nombre = "";
		con = DBConn.DataSourceCon();

	
		
			sql_statement = con.prepareStatement(sql_ExisteUsrTer);
			sql_statement.setString(1, user);            
			
			rs_eUser = sql_statement.executeQuery();

			while(rs_eUser.next()){
				id = rs_eUser.getInt("id");
				nombre= rs_eUser.getString("nombre");
			}
			
			rs_eUser.close();
			Usuario retorno = new Usuario(id, nombre, user, "");
			return retorno;
	}

	public Integer obtenerAgencia() throws SQLException {

		String sql_Agencia = "SELECT Valor FROM Configuracion WHERE Parametro =?";
		
		PreparedStatement sql_statement = null;
		Connection con = null;
		ResultSet rs_Agencia = null;
		Integer id = null;
		con = DBConn.DataSourceCon();
		
		sql_statement = con.prepareStatement(sql_Agencia);
		sql_statement.setString(1, Constants.getIdAgencia());            
		
		rs_Agencia = sql_statement.executeQuery();
		
		while(rs_Agencia.next()){
			id = rs_Agencia.getInt("Valor");	
		}
		
		rs_Agencia.close();
		return id;
	}

	public boolean verificarDatosVentas(Venta venta) throws SQLException {
		
		String sql_ExisteVenta = "SELECT COUNT(Id_Ticket) AS Cantidad " +
				"FROM Ventas " +
				"WHERE Id_Ticket_IMM = ? " +
				"AND Matricula = ?";
		
		PreparedStatement sql_statement = null;
		Connection con = null;
		ResultSet rs_eUser = null;
		Integer count = 0;
		
		con = DBConn.DataSourceCon();

		sql_statement = con.prepareStatement(sql_ExisteVenta);
		sql_statement.setInt(1, venta.getId_imm());
		sql_statement.setString(2, venta.getMatricula());
		
		rs_eUser = sql_statement.executeQuery();
		rs_eUser.next();
		
		count = rs_eUser.getInt("Cantidad");
		rs_eUser.close();
		
		if(count!=0){
			return true;
		}else{
			return false;
		}
	}

	public boolean verificarVentaAnulada(Venta venta) throws SQLException {
		// TODO Auto-generated method stub
		String sql_ExisteVenta = "SELECT COUNT(Ventas.Id_Ticket) AS Cantidad " +
				"FROM Anulaciones " +
				"JOIN Ventas ON  Ventas.Id_Ticket=Anulaciones.Id_Ticket " +
				"WHERE Ventas.Id_Ticket_IMM = ? "; 
		
		PreparedStatement sql_statement = null;
		Connection con = null;
		ResultSet rs_eUser = null;
		Integer count = 0;
		
		con = DBConn.DataSourceCon();

		sql_statement = con.prepareStatement(sql_ExisteVenta);
		sql_statement.setInt(1, venta.getId_imm());
		
		rs_eUser = sql_statement.executeQuery();
		rs_eUser.next();
		
		count = rs_eUser.getInt("Cantidad");
		rs_eUser.close();
		
		if(count!=0){
			return true;
		}else{
			return false;
		}
	}

	public DataSocketBuscar buscarDataVenta(Integer id_Ticket_IMM) throws SQLException {
		DataSocketBuscar venta = new DataSocketBuscar();
		
		String sql_Venta = "SELECT Ventas.Id_Ticket, " +
				"Ventas.Id_Ticket_IMM, " +
				"Ventas.Matricula, " +
				"Ventas.FechaVenta, " +
				"Ventas.FechaInicio, " +
				"Ventas.Minutos, " +
				"Ventas.Importe, " +
				"Ventas.Id_Terminal, " +
				"Ventas.Id_Usuario, " +
				"Anulaciones.Id_Anulado " +
				"FROM Ventas " +
				"LEFT JOIN Anulaciones ON Anulaciones.Id_Ticket = Ventas.Id_Ticket " +
				"WHERE Ventas.Id_Ticket_IMM = ?";
		
		PreparedStatement sql_statement = null;
		Connection con = null;
		ResultSet rs_eVenta = null;
		
		con = DBConn.DataSourceCon();

		sql_statement = con.prepareStatement(sql_Venta);
		sql_statement.setInt(1, id_Ticket_IMM); 
		
		rs_eVenta = sql_statement.executeQuery();
		while(rs_eVenta.next()){
			venta.setFechaVenta(rs_eVenta.getDate("FechaVenta"));
			venta.setFechaInicio(rs_eVenta.getDate("FechaInicio"));
			venta.setMinutos(rs_eVenta.getInt("Minutos"));
			venta.setImporte(rs_eVenta.getDouble("Importe"));
			venta.setId_terminal(rs_eVenta.getInt("Id_Terminal"));
			venta.setMatricula(rs_eVenta.getString("Matricula"));
			venta.setError(rs_eVenta.getInt("Id_Anulado"));
		}
		
		rs_eVenta.close();
		
		return venta;
	}

	public Venta buscarVenta(Integer id_Ticket_IMM) throws SQLException {
		Venta venta = new Venta();
		
		String sql_Venta = "SELECT Ventas.Id_Ticket, " +
				"Ventas.Id_Ticket_IMM, " +
				"Ventas.Matricula, " +
				"Ventas.FechaVenta, " +
				"Ventas.FechaInicio, " +
				"Ventas.Minutos, " +
				"Ventas.Importe, " +
				"Ventas.Id_Terminal, " +
				"Ventas.Id_Usuario " +
				"FROM Ventas " +
				"WHERE Ventas.Id_Ticket_IMM = ?";
		
		PreparedStatement sql_statement = null;
		Connection con = null;
		ResultSet rs_eVenta = null;
		
		con = DBConn.DataSourceCon();

		sql_statement = con.prepareStatement(sql_Venta);
		sql_statement.setInt(1, id_Ticket_IMM); 
		
		rs_eVenta = sql_statement.executeQuery();
		while(rs_eVenta.next()){
			venta.setId(rs_eVenta.getInt("Id_Ticket"));
			venta.setId_imm(rs_eVenta.getInt("Id_Ticket_IMM"));
			venta.setMatricula(rs_eVenta.getString("Matricula"));
			venta.setFechaVenta(rs_eVenta.getDate("FechaVenta"));
			venta.setFechaInicio(rs_eVenta.getDate("FechaInicio"));
			venta.setMinutos(rs_eVenta.getInt("Minutos"));
			venta.setImporte(rs_eVenta.getDouble("Importe"));
			venta.setId_terminal(rs_eVenta.getInt("Id_Terminal"));
			venta.setId_usuario(rs_eVenta.getInt("Id_Usuario"));
		}
		
		rs_eVenta.close();
		
		return venta;
	}

	

}
